#include "lgaimageprocess.h"
#include "qhalconwindow.h"

#include <QDateTime>
#include <QHash>
#include <math.h>
#include "lgapackagemanager.h"
#include "xlsxdocument.h"
#include "imagesavemanager.h"
const int FULL_W_H = 7000;
const double MILS_PIXS = 5120 / 54.0 * 0.0254;
using namespace HalconCpp;
typedef struct _POS_INTEN
{
	double r;
	double c;
	double m;
}POS_INTEN;

extern double distance(QPointF p1, QPointF p2);

BOOL CalcDamageRegion(QList<QPointF> &ballsStd, QList<QPointF>balls1, int difCount, double dist)
{
	for (int idx = 0; idx < ballsStd.size(); )
	{
		const QPointF p = ballsStd[idx];
		int b = 0;
		for each (QPointF p1 in balls1)
		{
			double d = distance(p, p1);
			if (d <= dist)
			{
				b++;
			}
		}
		if (b == 0)
		{
			//qDebug() << b;
			++idx;
		}
		else {
			ballsStd.removeAt(idx);
		}
	}

	return ballsStd.count() == difCount;
}

double GetGrayRatio(HImage im, HRegion r, int dif, double m)
{
	HTuple his;
	r.GrayHisto(im, &his);
	double ratio = 0;

	for (int j = m - dif; j <= m + dif; j++)
	{
		if (j>=0 && j<256)
		{
			ratio += his[j].D();
		}
	}
	return ratio;
}

void SaveImage(HalconCpp::HImage img, HalconCpp::HRegion reg, QString name)
{
	if (reg.IsInitialized())
	{
		img.ReduceDomain(reg.Union1()).CropDomain().WriteImage("bmp", 0, name.toUtf8());
	}
}

void LgaImageProcess::GenFullImageSp7()
{
	//BgaPackageManager::PACKAGE_INFO info = BgaPackageManager::getInstance()->GetPackageInfo();
	PACKAGE_INFO info = StaticFunction::GetPackageInfo();
	int c = m_imagePadList.count();
	QList<HImage> imgListBall;
	HImage ImgCapMidFull;

	{
		Hlong ImageWidth, ImageHeight;
		m_imagePadList[0].GetImageSize(&ImageWidth, &ImageHeight);
		HRegion r1;
		GenRectangle1(&r1, ImageHeight*0.4, ImageWidth*0.4, ImageHeight*0.6, ImageWidth*0.6);
		double dev;
		m_meanGray = r1.Intensity(m_imagePadList[0], &dev);
	}

	for (int i = 0; i < c; i++)
	{
		HImage imageBall = m_imagePadList[i].CopyImage();
		HImage imageSubstrate = m_imageSubList[i].CopyImage();

		//rotate
		{
			HRegion SelectedRegions = imageBall.GaussFilter(3).Threshold(m_meanGray +10, 255).Connection().DilationRectangle1(50, 20).Union1().Connection().SelectShapeStd("max_area", 70);
			double row, column, phi, len1, len2;
			SelectedRegions.SmallestRectangle2(&row, &column, &phi, &len1, &len2);
			double rotateDeg = phi > 0 ? 90 - phi * 180 / M_PI : -90 - phi * 180 / M_PI;
			imageBall = imageBall.RotateImage(rotateDeg, "constant");
			imageSubstrate = m_imageSubList[i].RotateImage(rotateDeg, "constant");
		}

		HRegion regionBall = imageBall.GaussFilter(3).Threshold(100, 255).Connection().DilationRectangle1(50, 20).Union1().Connection().SelectShapeStd("max_area", 70).ErosionRectangle1(25, 11);
		HRegion RegionTrans2 = regionBall.ShapeTrans("rectangle1");
		Hlong  Row12, Column12, Row2, Column2;
		RegionTrans2.SmallestRectangle1(&Row12, &Column12, &Row2, &Column2);
		HRegion regionSub;
		HRegion r1;
		if (i == 0)
		{
			GenRectangle1(&r1, Row12, Column12 - info.edgeGap, Row2 + info.edgeGap, Column2);
		}
		else if (i == 1)
		{
			GenRectangle1(&r1, Row12 - info.edgeGap, Column12 - info.edgeGap, Row2, Column2);
		}
		else if (i == 2)
		{
			GenRectangle1(&r1, Row12 - info.edgeGap, Column12, Row2, Column2 + info.edgeGap);
		}
		else if (i == 3)
		{
			GenRectangle1(&r1, Row12, Column12, Row2 + info.edgeGap, Column2 + info.edgeGap);
		}
		regionSub = r1.Difference(RegionTrans2);
		{
			HTuple hRows, hColuomns;
			regionSub.Union1().GetRegionPoints(&hRows, &hColuomns);
			HTuple hValues = imageSubstrate.GetGrayval(hRows, hColuomns);
			imageBall.SetGrayval(hRows, hColuomns, hValues);
		}
		imageBall = imageBall.ReduceDomain(regionBall.ConcatObj(regionSub).Union1()).CropDomain();
		imgListBall.append(imageBall);
	}
	if (imgListBall.count()!=4)
	{
		qDebug()<<"pad image error";
		m_curRes = ResultManager::ERR_WRONG_IMAGE;
		return;
	}
	Hlong mergeGap = 30;
	Hlong w1, h1, w2, h2, w3, h3, w4, h4;

	imgListBall[0].GetImageSize(&w1, &h1);
	imgListBall[1].GetImageSize(&w2, &h2);
	imgListBall[2].GetImageSize(&w3, &h3);
	imgListBall[3].GetImageSize(&w4, &h4);

	Hlong maxCC1 = MAX(MAX(w1 , w2), MAX(w3 , w4));
	Hlong maxRR1 = MAX(MAX(h1 , h4), MAX(h2 , h3));
	
	HImage img, imgFull;
	GenImageConst(&img, "byte", maxCC1*2+ mergeGap, maxRR1 * 2 + mergeGap);
	GenImageProto(img, &imgFull, 0);
	Hlong difR[4] = { maxRR1+mergeGap, maxRR1-h2, maxRR1 - h3, maxRR1 + mergeGap };
	Hlong difC[4] = { maxCC1 - w1, maxCC1 - w1, maxCC1 +mergeGap, maxCC1 + mergeGap };
	for (int i = 0; i < imgListBall.count(); i++)
	{
		HImage imageBall = imgListBall[i];
		HTuple rows, columns;
		imageBall.GetDomain().GetRegionPoints(&rows, &columns);
		HTuple hValues = imageBall.GetGrayval(rows, columns);
		imgFull.SetGrayval(rows + difR[i], columns + difC[i], hValues);
	}

	m_imgResultPad = m_imgResultSub = imgFull.CopyImage();	
	if (m_imageCapList.count() == 0)
	{
		qDebug() << "cap image error";
		m_curRes = ResultManager::ERR_WRONG_IMAGE;
		return;
	}
	HImage imageCap = m_imageCapList[0];
	QString type = LgaPackageManager::getInstance()->getPackageType().toUpper();
	
	//rotate
	{
		/*HRegion Rectangle;
		GenRectangle1(&Rectangle, 1200, 1000, 1500, 1500);*/
		HImage ImageGauss = imageCap.GaussFilter(3);
	/*	double dev;
		double mean = ImageGauss.Intensity(Rectangle, &dev);*/
		//m_meanGray = mean;
		HRegion SelectedRegions = ImageGauss.Threshold(120, 255).Connection().FillUp().OpeningCircle(5.5).Connection().SelectShape("width", "and", 100, 150).SelectShape("height", "and", 40, 80).FillUp().DilationCircle(50.5).Union1().Connection().SelectShapeStd("max_area", 70);
		if (type.indexOf("SP5") != -1)
		{
			SelectedRegions = ImageGauss.Threshold(120, 255).Connection().FillUp().OpeningCircle(5.5).Connection().SelectShape("width", "and", 40, 80).SelectShape("height", "and", 100, 150).FillUp().DilationCircle(50.5).Union1().Connection().SelectShapeStd("max_area", 70);
		}
		double row, column, phi, len1, len2;
		SelectedRegions.SmallestRectangle2(&row, &column, &phi, &len1, &len2);
		double rotateDeg = -phi * 180 / M_PI;
		imageCap = m_imageCapList[0].RotateImage(rotateDeg, "constant");
	}
	{
		HImage ImageGauss = imageCap.GaussFilter(3);
		HRegion Rectangle;
		GenRectangle1(&Rectangle, 1600, 1600, 3400, 3400);
		HRegion SelectedRegions = ImageGauss.ReduceDomain(Rectangle).Threshold(120, 255).Connection().FillUp().OpeningCircle(5.5).Connection().SelectShape("width", "and", 85, 150).SelectShape("height", "and", 40, 80).FillUp().DilationCircle(50.5).Union1().Connection().SelectShapeStd("max_area", 70).ErosionCircle(30.5).FillUp();
		if (type.indexOf("SP5") != -1)
		{
			SelectedRegions = ImageGauss.ReduceDomain(Rectangle).Threshold(120, 255).Connection().FillUp().OpeningCircle(5.5).Connection().SelectShape("width", "and", 40, 80).SelectShape("height", "and", 85, 150).FillUp().DilationCircle(50.5).Union1().Connection().SelectShapeStd("max_area", 70).ErosionCircle(30.5).FillUp();
		}
		ImgCapMidFull = imageCap.ReduceDomain(SelectedRegions).CropDomain();
	}

	//middle caps
	Hlong Width5, Width6, Height5, Height6;
	imgFull.GetImageSize(&Width5, &Height5);
	ImgCapMidFull.GetImageSize(&Width6, &Height6);
	{
		HTuple rows, columns;
		ImgCapMidFull.GetDomain().GetRegionPoints(&rows, &columns);
		HTuple hValues = ImgCapMidFull.GetGrayval(rows, columns);
		imgFull.SetGrayval(rows + (Height5 - Height6) / 2, columns + (Width5 - Width6) / 2, hValues);
		m_regionCaps = ImgCapMidFull.GetDomain().MoveRegion((Height5 - Height6) / 2, (Width5 - Width6) / 2);
	}
	m_imgResult = m_imgResultCap = imgFull;
}

LgaImageProcess::LgaImageProcess()
{
	QString appName = QCoreApplication::applicationName();
	QSettings app(appName, "Debug");
	QStringList list;
	list << "bmp" << "jpg" << "png fastest";

	int index = app.value("imagetype").toInt();
	if (index >= list.count() || index < 0)
	{
		index = 0;
	}
	m_imgType = list[index];

	m_curRes = ResultManager::ERR_MAX;
}

void LgaImageProcess::SetBallImage(HalconCpp::HImage image, int index)
{
	qDebug() << __FUNCTION__ << "++" << index;
	if (!image.IsInitialized())
	{
		m_curRes = ResultManager::ERR_WRONG_IMAGE;
		qDebug() <<  "ResultManager::ERR_WRONG_IMAGE";
		return;
	}
	m_imagePadList.append(image);

	QString appName = QCoreApplication::applicationName();
	QSettings app(appName, "Debug");
	int t = app.value("tempimage").toInt();
	if (t == 1 && image.IsInitialized())
	{
		QStringList list = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation);
		QString path = QString("%1/temp_pad%2").arg(list.first()).arg(index);
		image.WriteImage(m_imgType.toUtf8(), 0, path.toUtf8());
	}
	qDebug() << __FUNCTION__ << "--" << index;
}

void LgaImageProcess::SetSubstrateImage(HalconCpp::HImage image, int index)
{
	qDebug() << __FUNCTION__ << "++" << index;
	if (!image.IsInitialized())
	{
		qDebug() << "ResultManager::ERR_WRONG_IMAGE5";
		m_curRes = ResultManager::ERR_WRONG_IMAGE;
		return;
	}
	m_imageSubList.append(image);

	QString appName = QCoreApplication::applicationName();
	QSettings app(appName, "Debug");
	int t = app.value("tempimage").toInt();
	if (t == 1 && image.IsInitialized())
	{
		QStringList list = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation);
		QString path = QString("%1/temp_edge%2").arg(list.first()).arg(index);
		image.WriteImage(m_imgType.toUtf8(), 0, path.toUtf8());
	}

	if (index == 1)
	{
		m_pod.padsPosList1.clear();
		m_pod.padsPosList2.clear();
		m_pod.padsPosList3.clear();
		m_pod.padsPosList4.clear();
		m_pod.capsPosList1.clear();
		GenEmptyObj(&m_regionDamagePad);
		GenEmptyObj(&m_regionPads);
		GenEmptyObj(&m_regionSubstrate);
		GenEmptyObj(&m_regionDamageSubstrate);
	}
	qDebug() << __FUNCTION__ << "--" << index;
}

void LgaImageProcess::SetCapImage(HalconCpp::HImage image, int index)
{
	qDebug() << __FUNCTION__ << "++" << index;
	if (!image.IsInitialized())
	{
		qDebug() << "ResultManager::ERR_WRONG_IMAGE6";
		m_curRes = ResultManager::ERR_WRONG_IMAGE;
		return;
	}
	m_imageCapList.append(image);
	//m_imageCapList[index-1] = image;
	QString appName = QCoreApplication::applicationName();
	QSettings app(appName, "Debug");
	int t = app.value("tempimage").toInt();
	if (t == 1 && image.IsInitialized())
	{
		QStringList list = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation);
		QString path = QString("%1/temp_cap%2").arg(list.first()).arg(index);
		image.WriteImage(m_imgType.toUtf8(), 0, path.toUtf8());
	}
	qDebug() << __FUNCTION__ << "--" << index;
}

BOOL LgaImageProcess::InitParameter()
{
	m_inspectParam = LgaPackageManager::getInstance()->GetParamFromFile();

	GenEmptyObj(&m_regionDamageCap);
	GenEmptyObj(&m_regionCaps);
	m_pod.capsPosList1.clear();

	m_listInspectEntity.clear();

	return TRUE;
}

int LgaImageProcess::TeachingAnalyze(HImage imgPad, HImage imgCap)
{
	qDebug() << __FUNCTION__ << "++";
	InitParameter();
	PACKAGE_INFO pi = StaticFunction::GetPackageInfo();

	QString type = LgaPackageManager::getInstance()->getPackageType().toUpper();

	QHalconWindow *imageView = (QHalconWindow *)m_widget;
	imageView->GetHalconBuffer()->ClearWindow();
	int ret = 0;
	Hlong ImageWidth, ImageHeight;

	imgPad.GetImageSize(&ImageWidth, &ImageHeight);
	imageView->GetHalconBuffer()->SetPart(0, 0, ImageHeight - 1, ImageWidth - 1);
	imageView->GetHalconBuffer()->DispObj(imgPad);

	HImage imgGauss = imgPad.GaussFilter(3);
	if (type.indexOf("SP5") != -1 || type.indexOf("SH5") != -1)
	{
		try
		{
			HRegion r = imgGauss.Threshold(50, 255).Connection().DilationRectangle1(50, 20).Union1().Connection().SelectShapeStd("max_area", 70).DilationCircle(33.5);
			HImage ir, ig, ib;
			ir = ig = ib = imgGauss;// .Decompose3(&ig, &ib);
			HRegion regPad = ig.ReduceDomain(r).ScaleImage(3.5, 0).Threshold(200, 255).OpeningCircle(10.5).FillUp().Connection().SelectShape("area", "and", 1500, 4000);
			if (regPad.CountObj() == pi.padNumbers)
			{
				imageView->GetHalconBuffer()->SetColor("green");
			}
			else
			{
				qDebug() << regPad.CountObj() << pi.padNumbers;
				imageView->GetHalconBuffer()->SetColor("red");
				ret = 1;
			}
			imageView->GetHalconBuffer()->DispObj(regPad);
		}
		catch (HalconCpp::HOperatorException e)
		{
			// this may happen, if the part is much too small or too big
			qDebug() << e.ErrorMessage() << e.ProcName();
			if (ret == 0)
			{
				ret = 1;
			}
		}
			
		try
		{
			HRegion r = imgCap.GaussFilter(3).ScaleImage(3, 0).Threshold(50, 255).Connection().FillUp().SelectShape("area", "and", 5000, 12000);
			qDebug() << r.CountObj();
			HRegion regCap = r.Union1().ShapeTrans("rectangle1").DilationCircle(100.5);

			double inten, der;
			inten = imgCap.Intensity(regCap, &der);
			HImage ir, ig, ib;
			ir = ig = ib = imgCap;// .GaussFilter(3).Decompose3(&ig, &ib);
	/*		HImage ih, is, iv;
			TransFromRgb(ir, ig, ib, &ih, &is, &iv, "hsv");*/
			HRegion rTemp1 = ir.ScaleImage(3, 0).Threshold(128, 255).Connection().SelectShape("area", "and", 3000, 10000);
			if (inten < 20)
			{
				qDebug() << "black cap";
				rTemp1 = ir.ScaleImage(3, 0).Threshold(20, 255).Connection().SelectShape("area", "and", 3000, 10000);
			}
			HRegion regc = rTemp1.FillUp().OpeningCircle(3.5).FillUp().ShapeTrans("convex").SortRegion("character", "true", "row");
				
			double areaMean = regc.Area().TupleMean();
			HRegion regCapBad1 = regc.SelectShape("area", "and", areaMean*0.1, areaMean*0.9);
			HRegion regCapBad2 = regc.SelectShape("area", "and", areaMean*1.1, areaMean*3.9);
			regc = regc.Difference(regCapBad1).Difference(regCapBad2);
			int c = regc.CountObj();
			imageView->GetHalconBuffer()->SetColor("green");
			if (c != pi.capNumbers)
			{
				imageView->GetHalconBuffer()->SetColor("red");
				if (ret == 0)
				{
					ret = 2;
				}
			}
			imageView->GetHalconBuffer()->DispObj(regc.Union1());
		}
		catch (HalconCpp::HOperatorException e)
		{
			// this may happen, if the part is much too small or too big
			qDebug() << e.ErrorMessage() << e.ProcName();
			if (ret == 0)
			{
				ret = 2;
			}
		}
		

	}

	else if (type.indexOf("AM5") != -1)
	{

		HRegion r1;
		GenRectangle1(&r1, ImageHeight*0.4, ImageWidth*0.4, ImageHeight*0.6, ImageWidth*0.6);
		double dev;
		double mean1 = r1.Intensity(imgGauss, &dev);
		HRegion rPad = imgGauss.Threshold(mean1 - 10, 255).Connection().SelectShape("area", "and", 2000, 3000).SelectShape("height", "and", 50, 70).DilationRectangle1(35, 55).Union1().Connection().SelectShape("area", "and", 3000000, 9999999);

		if (rPad.CountObj() == 0)
		{
			ret = 1;
		}
		else
		{
			HImage ir, ig, ib;
			ir = ig = ib = imgGauss.ReduceDomain(rPad.Union1());// .Decompose3(&ig, &ib);
			//HImage ih, is, iv;
			//TransFromRgb(ir, ig, ib, &ih, &is, &iv, "hsv");
			imgGauss = ig.GaussFilter(3);
			double deviation, meanGray;
			meanGray = imgGauss.Intensity(imgGauss.GetDomain(), &deviation);
			HRegion regPad = imgGauss.Threshold(meanGray, 255).FillUp().Connection().SelectShape("area", "and", 1500, 4000);
			if (regPad.CountObj() == pi.padNumbers)
			{
				imageView->GetHalconBuffer()->SetColor("green");
			}
			else
			{
				qDebug() << regPad.CountObj() << pi.padNumbers;
				imageView->GetHalconBuffer()->SetColor("red");
				ret = 1;
			}
			imageView->GetHalconBuffer()->DispObj(regPad);
		}
	}
	imageView->GetHalconBuffer()->FlushBuffer();
	qDebug() << "teaching test result:" << ret;
	return ret;
}

ResultManager::ERROR_TYPE LgaImageProcess::GetInspectResult()
{
	qDebug() << __FUNCTION__ << "++";
	QString type = LgaPackageManager::getInstance()->getPackageType().toUpper();
	if (type.indexOf("SP7") != -1 || type.indexOf("SP5") != -1)
	{
		try
		{
			InitParameter();
			GenFullImageSp7();
			return GetInspectResultSP7();
		}
		catch (HalconCpp::HException e)
		{
			qDebug() << "Exception 1:" << e.ProcName() << e.ErrorCode() << e.ErrorMessage();
			m_curRes = ResultManager::ERR_WRONG_IMAGE;
		}	
	}
	else if (type.indexOf("AM5") != -1)
	{
		try
		{
			InitParameter();
			return GetInspectResultAM5();
		}
		catch (HalconCpp::HException e)
		{
			qDebug() << "Exception 1:" << e.ProcName() << e.ErrorCode() << e.ErrorMessage();
			m_curRes = ResultManager::ERR_WRONG_IMAGE;
		}
	}
	else
	{
		m_curRes = ResultManager::ERR_PASS;
	}
	return m_curRes;
}

ResultManager::ERROR_TYPE LgaImageProcess::GetInspectResultSP7()
{
	qDebug() << __FUNCTION__ << "++";
	m_curRes = ResultManager::ERR_PASS;
	//HRegion r1;
	//GenRectangle1(&r1, 2000, 2000, 3000, 3000);
	//double dev;
	//double mean1 = r1.Intensity(m_imgResultPad, &dev);
	HRegion rPad1 = m_imgResultPad.GaussFilter(3).Threshold(m_meanGray + 10, 255).Connection().DilationRectangle1(50, 20).Union1().Connection();
	double areaMax = rPad1.SelectShapeStd("max_area", 70).Area();
	HRegion rPad = rPad1.SelectShape("area", "and", areaMax*0.8, areaMax) ;
	if (rPad.CountObj() == 0)
	{
		m_curRes = ResultManager::ERR_WRONG_IMAGE;
		qDebug() << __FUNCTION__ << "ERR_WRONG_IMAGE";
		return m_curRes;
	}
	m_regionPads = rPad.Union1();
	HRegion regAll = m_regionPads.DilationRectangle1(220, 350).ShapeTrans("rectangle2");
	m_regionSubstrate = regAll.Difference(m_regionPads.ShapeTrans("convex"));

	try
	{
		InspectPads();
	}
	catch (HalconCpp::HOperatorException e)
	{
		qDebug() << "InspectPadsSP3" << e.ErrorMessage() << e.ProcName();
		m_curRes = ResultManager::ERR_WRONG_IMAGE;
		goto res;
	}
	try
	{
		InspectCaps(120, 4000, 10000, 3, m_inspectParam.capMiniAreaRatio / 100.0);
	}
	catch (HalconCpp::HOperatorException e)
	{
		qDebug() << "InspectCaps" << e.ErrorMessage() << e.ProcName();
		m_curRes = ResultManager::ERR_WRONG_IMAGE;
		goto res;
	}
	InspectSubstrate();
res:
	if (m_regionDamageSubstrate.CountObj() > 0 && m_inspectParam.bChipping)
	{
		m_curRes = ResultManager::ERR_SUBSTRATE_DAMAGE;
	}

	if (m_regionDamageCap.CountObj() > 0 && m_inspectParam.bCapDamaged)
	{
		m_curRes = ResultManager::ERR_CAP_DAMAGE;
	}

	if (m_regionDamagePad.CountObj() > 0 && m_inspectParam.bPadDamaged)
	{
		m_curRes = ResultManager::ERR_PAD_DAMAGE;
	}

	if (m_inspectParam.bPadDamaged && (m_curRes == ResultManager::ERR_PASS || m_curRes == ResultManager::ERR_SUBSTRATE_DAMAGE))
	{
		qDebug() << __FUNCTION__ << "SavePodToFile";
		LgaPackageManager::getInstance()->SavePodToFile(m_pod);
	}

	qDebug() << __FUNCTION__ << "-------------";
	return m_curRes;
}

ResultManager::ERROR_TYPE LgaImageProcess::GetInspectResultAM5()
{
	qDebug() << __FUNCTION__ << "++";
	m_curRes = ResultManager::ERR_PASS;
	Hlong ImageWidth, ImageHeight;
	m_imagePadList[0].GetImageSize(&ImageWidth, &ImageHeight);
	HRegion r1;
	GenRectangle1(&r1, ImageHeight*0.4, ImageWidth*0.4, ImageHeight*0.6, ImageWidth*0.6);
	double dev;
	m_meanGray = r1.Intensity(m_imagePadList[0], &dev);
	{
		HRegion rPad = m_imagePadList[0].GaussFilter(3).Threshold(m_meanGray + 10, 255).Connection().FillUp().OpeningCircle(10.5).Connection().SelectShape("area", "and", 2000, 5000).SelectShape("height", "and", 50, 80).DilationRectangle1(35, 55).Union1().Connection().SelectShapeStd("max_area", 70);
		if (rPad.CountObj() == 0)
		{
			m_curRes = ResultManager::ERR_WRONG_IMAGE;
			qDebug() << __FUNCTION__ << "ERR_WRONG_IMAGE";
			return m_curRes;
		}
		double row, column, phi, len1, len2;
		rPad.SmallestRectangle2(&row, &column, &phi, &len1, &len2);

		double rotateDeg = - phi * 180 / M_PI;
		m_imagePadList[0] = m_imagePadList[0].RotateImage(rotateDeg, "constant");
		m_imageSubList[0] = m_imageSubList[0].RotateImage(rotateDeg, "constant");
	}
	HRegion rPad = m_imagePadList[0].GaussFilter(3).Threshold(m_meanGray + 10, 255).Connection().FillUp().OpeningCircle(10.5).Connection().SelectShape("area", "and", 2000, 5000).SelectShape("height", "and", 50, 80).DilationRectangle1(35, 55).Union1().Connection().SelectShapeStd("max_area", 70);
	if (rPad.CountObj() == 0)
	{
		m_curRes = ResultManager::ERR_WRONG_IMAGE;
		qDebug() << __FUNCTION__ << "ERR_WRONG_IMAGE";
		return m_curRes;
	}
	if (rPad.CountObj() == 0)
	{
		m_curRes = ResultManager::ERR_WRONG_IMAGE;
		qDebug() << __FUNCTION__ << "ERR_WRONG_IMAGE";
		return m_curRes;
	}
	m_regionPads = rPad.Union1();
	HRegion regAll = m_regionPads.DilationRectangle1(200, 350).ShapeTrans("rectangle2");
	m_regionSubstrate = regAll.Difference(rPad.Union1().FillUp());
	
	m_curRes = ResultManager::ERR_PASS;

	HImage resutImage;
	GenImageConst(&resutImage, "byte", ImageWidth, ImageHeight);
	//Compose3(resutImage.GenImageProto(0), resutImage.GenImageProto(0), resutImage.GenImageProto(0), &resutImage);

	HTuple rows, columns;
	//HImage imageAddR, imageAddG, imageAddB, imageDumpR, imageDumpG, imageDumpB;

	//imageDumpR = resutImage.Decompose3(&imageDumpG, &imageDumpB);

	//imageAddR = m_imagePad[0].Decompose3(&imageAddG, &imageAddB);
	m_regionPads.GetRegionPoints(&rows, &columns);
	resutImage.SetGrayval(rows, columns, m_imagePadList[0].GetGrayval(rows, columns));
	//imageDumpG.SetGrayval(rows, columns, imageAddG.GetGrayval(rows, columns));
	//imageDumpB.SetGrayval(rows, columns, imageAddB.GetGrayval(rows, columns));

	//imageAddR = c.Decompose3(&imageAddG, &imageAddB);
	m_regionSubstrate.GetRegionPoints(&rows, &columns);
	resutImage.SetGrayval(rows, columns, m_imageSubList[0].GetGrayval(rows, columns));
	//imageDumpG.SetGrayval(rows, columns, imageAddG.GetGrayval(rows, columns));
	//imageDumpB.SetGrayval(rows, columns, imageAddB.GetGrayval(rows, columns));
	//Compose3(imageDumpR, imageDumpG, imageDumpB, &resutImage);
	m_imgResult = m_imgResultPad = m_imgResultSub = resutImage;
	try
	{
		InspectPads();
	}
	catch (HalconCpp::HOperatorException e)
	{
		qDebug() << "InspectPadsSP3" << e.ErrorMessage() << e.ProcName();
		m_curRes = ResultManager::ERR_WRONG_IMAGE;
		goto res;
	}
	{//pin1
		Hlong hv_xy = 120;
		Hlong row1, row2, column1, column2;
		m_regionPads.Union1().SmallestRectangle1(&row1, &column1, &row2, &column2);

		HObject  ho_Contour, ho_Region;
		HTuple hv_rows, hv_columns;
		hv_rows.Clear();
		hv_rows.Append(row1 - hv_xy);
		hv_rows.Append(row1 - hv_xy);
		hv_rows.Append(row1 + hv_xy);
		hv_rows.Append(row1 - hv_xy);
		hv_columns.Clear();
		hv_columns[0] = column2 - hv_xy;
		hv_columns[1] = column2 + hv_xy;
		hv_columns[2] = column2 + hv_xy;
		hv_columns[3] = column2 - hv_xy;
		GenContourPolygonXld(&ho_Contour, hv_rows, hv_columns);
		GenRegionContourXld(ho_Contour, &ho_Region, "filled");
		//	m_regionAllBalls = m_regionAllBalls.Union1().Difference(ho_Region).Connection();
		m_regionSubstrate = m_regionSubstrate.Union1().Difference(ho_Region);
	}
	InspectSubstrate();
res:
	if (m_regionDamageSubstrate.CountObj() > 0 && m_inspectParam.bChipping)
	{
		m_curRes = ResultManager::ERR_SUBSTRATE_DAMAGE;
	}

	if (m_regionDamagePad.CountObj() > 0 && m_inspectParam.bPadDamaged)
	{
		m_curRes = ResultManager::ERR_PAD_DAMAGE;
	}

	if (m_inspectParam.bPadDamaged && (m_curRes == ResultManager::ERR_PASS || m_curRes == ResultManager::ERR_SUBSTRATE_DAMAGE))
	{
		qDebug() << __FUNCTION__ << "SavePodToFile";
		LgaPackageManager::getInstance()->SavePodToFile(m_pod);
	}

	qDebug() << __FUNCTION__ << "--";
	return m_curRes;
}

void LgaImageProcess::InspectPads()
{
	PACKAGE_INFO pi = StaticFunction::GetPackageInfo();
	HImage ig = m_imgResultPad.ReduceDomain(m_regionPads.Union1());// .Decompose3(&ig, &ib);
	HImage imgGauss = ig.GaussFilter(3);

	HRegion regPad = imgGauss.Threshold(m_meanGray + 10, 255).FillUp().Connection().SelectShape("area", "and", 1500, 5000);
	QString type = LgaPackageManager::getInstance()->getPackageType().toUpper();



	HRegion regionDamage;
	GenEmptyObj(&regionDamage);
	int c = regPad.CountObj();
	qDebug() <<"pad: " << c << "vs" << pi.padNumbers;
	if (c == pi.padNumbers)
	{
		double rowCenter, columnCenter;
		regPad.Union1().AreaCenter(&rowCenter, &columnCenter);	
		m_pod.padsCenter1.setX(rowCenter);
		m_pod.padsCenter1.setY(columnCenter);

		HTuple row, col, a;
		AreaCenter(regPad, &a, &row, &col);

		for (size_t i = 0; i < pi.padNumbers; i++)
		{
			QPointF p(row[i].D(), col[i].D());
			m_pod.padsPosList1.push_back(p);
		}
	}
	else if (c < pi.padNumbers)
	{
		LgaPackageManager::POD_INFO pod = LgaPackageManager::getInstance()->GetPodFromFile();
		QList<QPointF> ballsStd = pod.padsPosList1;
		QPointF padsCenter = pod.padsCenter1;
		if (ballsStd.count() == 0)
		{
			m_regionDamagePad = m_regionDamagePad.ConcatObj(regPad);
		}
		else if (ballsStd.count() == pi.padNumbers && regPad.CountObj() > 0)
		{
			double dr, dc;
			regPad.Union1().AreaCenter(&dr, &dc);
			QList<QPointF> balls1;
			{
				HTuple rs, cs;
				HTuple areas = regPad.AreaCenter(&rs, &cs);
				for (int i = 0; i < areas.Length(); i++)
				{
					balls1.push_back(QPointF(rs[i].D() + (padsCenter.x() - dr), cs[i].D() + (padsCenter.y() - dc)));
				}
			}

			int dd = 15;
			while (dd <= 100)
			{
				qDebug() << "CalcDamageRegion" << dd;
				BOOL b = CalcDamageRegion(ballsStd, balls1, pi.padNumbers - c, dd);
				if (!b)
				{
					dd += 3;
				}
				else
				{
					HObject ho3;
					for each (QPointF p in ballsStd)
					{
						HObject circle;
						GenCircle(&circle, p.x() - (padsCenter.x() - dr), p.y() - (padsCenter.y() - dc), 30);
						if (!ho3.IsInitialized())
						{
							ho3 = circle;
						}
						else
						{
							ho3 = ho3.ConcatObj(circle);
						}
						{
							INSPECT_ENTITY ie;
							//ie.bHasPin1 = bHasPin1;
							ie.coordinate = p;
							ie.reason = FAIL_PAD_DAMAGE;
							ie.reasonDesc = "The pad is damaged. ";
							ie.parameterDesc = "The pad is badly damaged. ";
							m_listInspectEntity.append(ie);
						}
					}
					regionDamage = ho3;

					break;
				}
			}
		}
	}

	HRegion regionPads = regPad.ShapeTrans("convex").ErosionCircle(3.5).SortRegion("character", "true", "row");
	QString appName = QCoreApplication::applicationName();
	QSettings app2(appName, "Config");
	/*app2.value("grayDiff").toInt();
	if (grayDiff <= 0)
	{
		grayDiff = 15;
	}*/

	int grayDiff = m_inspectParam.discolorValue;
	HTuple mean, dev;
	mean = regionPads.Intensity(ig, &dev);
	
	for (int i = 0; i < c; i++)
	{
		HRegion r2 = regionPads.SelectObj(i + 1);
		double ratio = GetGrayRatio(ig, r2, grayDiff, mean[i].D()) * 100;
		if (ratio < 100 - m_inspectParam.miniAreaRatio)
		{
			if (regionDamage.IsInitialized())
			{
				regionDamage = regionDamage.ConcatObj(r2);
			}
			else
			{
				regionDamage = r2;
			}
		}
	}
	HTuple rs, cs;
	HTuple areas = regionPads.AreaCenter(&rs, &cs);
	QList<POS_INTEN>listMean;
	HTuple ddd;
	HTuple mmm = regionPads.Intensity(ig, &ddd);
	
	for (int i = 0; i < areas.Length(); i++)
	{
		POS_INTEN v;
		v.r = rs[i].D();
		v.c = cs[i].D();
		v.m = mmm[i].D();
		listMean.push_back(v);
	}
	if (m_inspectParam.bDisColor)
	{
		int colorDifCount = app2.value("colorDiffCount").toInt();
		if (colorDifCount <= 0)
		{
			colorDifCount = 3;
		}

		QList<QPointF>listBad;
		for (int i = 0; i < listMean.count(); i++)
		{
			POS_INTEN v1 = listMean[i];
			QList <double>list;
			int start = MAX(0, i - 144);
			int end = MIN(listMean.count(), i + 144);
			for (int j = start; j < end; j++)
			{
				POS_INTEN v2 = listMean[j];
				double distance = (v1.r - v2.r)*(v1.r - v2.r) + (v1.c - v2.c)*(v1.c - v2.c);
				if (distance < 14400)
				{
					list.push_back(v2.m);
				}
			}
			if (list.count() == 7)
			{
				int count = 0;
				for each (double mean2 in list)
				{
					if (abs(mean2 - v1.m) > m_inspectParam.discolorValue)
					{
						count++;
					}
				}
				if (count >= colorDifCount)
				{
					listBad.append(QPointF(v1.r, v1.c));
				}
			}
		}
#if 0
		//HImage h, s, v;
		//TransFromRgb(ir, ig, ib, &h, &s, &v, "hsv");
		HImage s2 = ir.GaussFilter(3).ReduceDomain(regionPads.Union1()).EquHistoImage();
		HRegion r1 = s2.Threshold(230, 255).Connection().SelectShape("area", "and", 1500, 2500).DilationCircle(20.5).Union1();
		if (r1.CountObj() > 0)
		{
			HRegion r2 = r1.Connection().SelectShape("area", "and", m_inspectParam.miniCountOfLarge * 6500, 999999999);
			if (r2.CountObj())
			{
				for (int i = 0; i < listBad.count(); i++)
				{
					QPointF p2 = listBad[i];
					HRegion circle;
					GenCircle(&circle, p2.x(), p2.y(), 12);
					HRegion regUnion = r2.Union1();
					HRegion r2 = regUnion.Intersection(circle);
					//	qDebug() << r2.CountObj() << r2.Area().I() << circle.Area().I();
					if (regUnion.Intersection(circle).Area().I() == circle.Area())
					{
						listBad.removeAt(i);
						i--;
					}
				}
				for (int i = 0; i < r2.CountObj(); i++)
				{
					double r, c;
					r2.SelectObj(i + 1).AreaCenter(&r, &c);
					INSPECT_ENTITY ie;
					ie.coordinate = QPointF(r, c);
					ie.reason = FAIL_PAD_DAMAGE;
					ie.reasonDesc = "The pad is damaged. ";
					ie.parameterDesc = "The pad is discolor. ";
					m_listInspectEntity.append(ie);
					//m_regionDamagePad = m_regionDamagePad.ConcatObj(r2);

					if (regionDamage.IsInitialized())
					{
						regionDamage = regionDamage.ConcatObj(r2);
					}
					else
					{
						regionDamage = r2;
					}
				}
				qDebug() << "large region color damaged count:" << r2.CountObj();
				//		ha.bResult = FALSE;
			}
		}
#endif
		int co = listBad.count();
		if (co > 0)
		{
			for each (QPointF p2 in listBad)
			{
				HRegion circle;
				GenCircle(&circle, p2.x(), p2.y(), 13);
				if (regionDamage.IsInitialized())
				{
					regionDamage = regionDamage.ConcatObj(circle);
				}
				else
				{
					regionDamage = circle;
				}
				INSPECT_ENTITY ie;
				ie.coordinate = p2;
				ie.reason = FAIL_PAD_DAMAGE;
				ie.reasonDesc = "The pad is damaged. ";
				ie.parameterDesc = "The pad is discolor. ";
				m_listInspectEntity.append(ie);
			}

		}
	}

	m_regionDamagePad = m_regionDamagePad.ConcatObj(regionDamage);
	if (m_regionDamagePad.CountObj() == 0 && c != regPad.CountObj())
	{
		m_regionDamagePad = regPad;
	}
}

void LgaImageProcess::InspectSubstrate()
{
	QString type = LgaPackageManager::getInstance()->getPackageType().toUpper();
	//HImage ir, ig, ib;
	//ir = m_imgResult.Decompose3(&ig, &ib);
	double chippingArea = m_inspectParam.miniChippingArea * MILS_PIXS * MILS_PIXS;
	HRegion r1 = m_imgResultSub.ReduceDomain(m_regionSubstrate).Threshold(150, 255).Connection().SelectShape("area", "and", chippingArea, 99999999).Connection();
	r1 = r1.SelectShape("width", "and", m_inspectParam.miniChippingWidth * MILS_PIXS, 99999).SelectShape("height", "and", m_inspectParam.miniChippingHeight * MILS_PIXS, 99999);
	if (type.indexOf("AM5") != -1)
	{
		Hlong Row1, Column1, Row2, Column2;
		m_regionSubstrate.SmallestRectangle1(&Row1, &Column1, &Row2, &Column2);
		HRegion Rectangle1, Rectangle2;
		GenRectangle1(&Rectangle1, Row1, (Column1 + Column2) / 2 - 600, Row1 + 200, (Column1 + Column2) / 2 + 600);
		GenRectangle1(&Rectangle2, Row2 - 200, (Column1 + Column2) / 2 - 600, Row2, (Column1 + Column2) / 2 + 600);
		HRegion Rectangle = Rectangle1.ConcatObj(Rectangle2).Union1();
		HRegion SelectedRegions = m_imgResult.ReduceDomain(Rectangle).Threshold(150, 255).Connection().SelectShape("width", "and", 220, 1000);
		qDebug() << SelectedRegions.CountObj();
		r1 = r1.Difference(SelectedRegions.Union1());
	}
	m_regionDamageSubstrate = r1.SelectShape("area", "and", chippingArea, 99999999).Connection();

	HTuple a, r, c;
	a = m_regionDamageSubstrate.Connection().AreaCenter(&r, &c);
	int count = m_regionDamageSubstrate.Connection().CountObj();	
	for (int i = 0; i < count; i++)
	{
		INSPECT_ENTITY ie;
		ie.coordinate = QPointF(r[i].D(), c[i].D());
		ie.reason = FAIL_SUBSTRATE_AREA;
		ie.value.substrateArea = a[i];
		ie.reasonDesc = "Substrate damage area";
		ie.parameterDesc = QString("%1 (0 ~ %2)").arg(ie.value.substrateArea).arg(chippingArea);
		m_listInspectEntity.append(ie);
	}
}

BOOL LgaImageProcess::InspectCaps(double threshold, double min, double max, int filter = 3, double dif = 0.33)
{
	//BgaPackageManager::PACKAGE_INFO info = BgaPackageManager::getInstance()->GetPackageInfo();
	PACKAGE_INFO info = StaticFunction::GetPackageInfo();
	HImage image = m_imgResultCap.GaussFilter(filter).ReduceDomain(m_regionCaps.Union1());
	HRegion r1 = image.Threshold(threshold, 255).Connection().OpeningCircle(5.5).FillUp().Connection();// .SelectShape("area", "and", 200, 500);
	HRegion caps = r1.SelectShape("area", "and", min, max);

	if (caps.CountObj() == 0)
	{
		qDebug() << "no cap";
		return FALSE;
	}
	double capArea = caps.Area().TupleMean();

	HRegion regionCaps = r1.SelectShape("area", "and", capArea*(1 - dif), capArea *(1 + dif));
	Hlong countCaps = regionCaps.CountObj();
	qDebug() << "caps:" << r1.CountObj() << countCaps;
	if (countCaps > 0)
	{
		double row, column;
		regionCaps.Union1().ShapeTrans("rectangle1").AreaCenter(&row, &column);
		m_pod.capsCenter1.setX(row);
		m_pod.capsCenter1.setY(column);
	}
	else
	{
		return FALSE;
	}
	for (int i = 1; i <= countCaps; i++)
	{
		HRegion r = regionCaps.SelectObj(i);
		double row, column;
		r.AreaCenter(&row, &column);
		m_pod.capsPosList1.push_back(QPointF(row, column));
	}

	int c = regionCaps.CountObj();
	if (c < info.capNumbers)
	{
		LgaPackageManager::POD_INFO pod = LgaPackageManager::getInstance()->GetPodFromFile();
		QList<QPointF> ballsStd = pod.capsPosList1;
		double rowCenter, columnCenter;
		regionCaps.Union1().AreaCenter(&rowCenter, &columnCenter);
		QList<QPointF> balls1;
		{
			HTuple rs, cs;
			HTuple areas = regionCaps.AreaCenter(&rs, &cs);

			double rGap = 0; //pod.capsCenter1.x() - rowCenter;
			double cGap = 0;// pod.capsCenter1.y() - columnCenter;
			for (int i = 0; i < areas.Length(); i++)
			{
				balls1.push_back(QPointF(rs[i].D() + rGap, cs[i].D() + cGap));
			}
		}

		int dd = 5;
		while (dd <= 130)
		{
			BOOL b = CalcDamageRegion(ballsStd, balls1, info.capNumbers - c, dd);
			//qDebug() << "CalcDamageRegion" << dd << balls1.count();
			if (!b)
			{
				dd += 2;
			}
			else
			{
				HObject ho3;
				for each (QPointF p in ballsStd)
				{
					HObject circle;
					GenCircle(&circle, p.x(), p.y(), 40);
					if (!ho3.IsInitialized())
					{
						ho3 = circle;
					}
					else
					{
						ho3 = ho3.ConcatObj(circle);
					}
				}
				m_regionDamageCap = ho3;

				break;
			}
		}

		double areaMean = regionCaps.Area().TupleMean();
		HRegion regCapBad1 = regionCaps.SelectShape("area", "and", areaMean*0.1, areaMean*0.9);
		HRegion regCapBad2 = regionCaps.SelectShape("area", "and", areaMean*1.1, areaMean*3.9);
		if (m_regionDamageCap.IsInitialized())
		{
			m_regionDamageCap = m_regionDamageCap.ConcatObj(regCapBad1).ConcatObj(regCapBad2);
		}
		else
		{
			m_regionDamageCap = regCapBad1.ConcatObj(regCapBad2);
		}
		return FALSE;
	}

	return TRUE;
}

void LgaImageProcess::ShowAllResult()
{
	ResultManager::ERROR_TYPE res = m_curRes;
 
	BOOL bRes = res == ResultManager::ERR_PASS;
	QHalconWindow *imageView = (QHalconWindow *)m_widget;
	imageView->GetHalconBuffer()->ClearWindow();
	Hlong ImageWidth, ImageHeight;	
	if (m_imgResult.IsInitialized())
	{
		m_imgResult.GetImageSize(&ImageWidth, &ImageHeight);
		imageView->GetHalconBuffer()->SetPart(0, 0, ImageHeight - 1, ImageWidth - 1);
		imageView->GetHalconBuffer()->DispObj(m_imgResult);
	}

	if (bRes)
	{
		HTuple font = imageView->GetHalconBuffer()->QueryFont();
		imageView->GetHalconBuffer()->SetFont(font + "-Bold-34");
		imageView->GetHalconBuffer()->DispText("Pass", "window", "top",
			"right", "green", "box_color", "black");
	}
	else
	{
		HTuple font = imageView->GetHalconBuffer()->QueryFont();
		imageView->GetHalconBuffer()->SetFont(font + "-Bold-34");
		imageView->GetHalconBuffer()->DispText("Fail", "window", "top",
			"right", "red", "box_color", "black");

		imageView->GetHalconBuffer()->SetFont(font + "-Bold-14");
		int height = 60;

		CONST int GAP = 20;
		QRect rect = m_widget->geometry();
		//int height2 = rect.height() - 35;
		if (res == ResultManager::ERR_CAP_DAMAGE)
		{
			imageView->GetHalconBuffer()->DispText("CAP damaged", "window", height,
				"right", "violet", "box_color", "black");
			height += 30;
		}
	/*	else if (res == ResultManager::ERR_CAP_NUM)
		{
			imageView->GetHalconBuffer()->DispText("CAP number error", "window", height,
				"right", "violet", "box_color", "black");
			height += 30;
		}*/
		else if (res == ResultManager::ERR_WRONG_IMAGE)
		{
			imageView->GetHalconBuffer()->DispText("Wrong image, please retest the chip", "window", height,
				"right", "red", "box_color", "black");
			height += 30;
		}
		else if (res == ResultManager::ERR_PAD_DAMAGE)
		{
			imageView->GetHalconBuffer()->DispText("Pad damaged", "window", height,
				"right", "red", "box_color", "black");
			height += 30;
		}
		else if (res == ResultManager::ERR_SUBSTRATE_DAMAGE)
		{
			imageView->GetHalconBuffer()->DispText("Substrate damaged", "window", height,
				"right", "turquoise", "box_color", "black");
			height += 30;
		}
	}
	
	CONST int GAP = 20;
	QRect rect = m_widget->geometry();
	imageView->GetHalconBuffer()->SetLineWidth(2);
	QString appName = QCoreApplication::applicationName();
	QSettings app(appName, "Debug");
	int t = app.value("testmode").toInt();
	if (m_inspectParam.bPadDamaged || t == 1)
	{
//#ifndef QT_NO_DEBUG
//		if (m_regionPads.IsInitialized())
//		{
//			imageView->GetHalconBuffer()->SetDraw("margin");
//			imageView->GetHalconBuffer()->SetColor("green");
//			imageView->GetHalconBuffer()->DispObj(m_regionPads);
//		}
////#endif
		if (m_regionDamagePad.IsInitialized())
		{
			imageView->GetHalconBuffer()->SetDraw("margin");
			imageView->GetHalconBuffer()->SetColor("red");
			imageView->GetHalconBuffer()->DispObj(m_regionDamagePad);
		}
	}
	if (m_inspectParam.bCapDamaged || t == 1)
	{
#ifndef QT_NO_DEBUG
		if (m_regionCaps.IsInitialized())
		{
			imageView->GetHalconBuffer()->SetDraw("margin");
			imageView->GetHalconBuffer()->SetColor("green");
			imageView->GetHalconBuffer()->DispObj(m_regionCaps);
		}
#endif
		if (m_regionDamageCap.IsInitialized())
		{
			imageView->GetHalconBuffer()->SetDraw("margin");
			imageView->GetHalconBuffer()->SetColor("turquoise");
			imageView->GetHalconBuffer()->DispObj(m_regionDamageCap);
		}
	}
	if (m_inspectParam.bChipping || t == 1)
	{
//#ifdef QT_DEBUG
		if (m_regionSubstrate.IsInitialized())
		{
			imageView->GetHalconBuffer()->SetDraw("margin");
			imageView->GetHalconBuffer()->SetColor("green");
			imageView->GetHalconBuffer()->DispObj(m_regionSubstrate);
		}
//#endif	
		if (m_regionDamageSubstrate.IsInitialized())
		{
			imageView->GetHalconBuffer()->SetDraw("margin");
			imageView->GetHalconBuffer()->SetColor("violet");
			imageView->GetHalconBuffer()->DispObj(m_regionDamageSubstrate);
		}
	}

	//if (res != ResultManager::ERR_PASS)
	//{
	//	QString appName = QCoreApplication::applicationName();
	//	QSettings app(appName, "Debug");
	//	int t = app.value("HideLabel").toInt();
	//	if (t != 1)
	//	{
	//		for (int i = 0; i < m_listInspectEntity.count(); i++)
	//		{
	//			INSPECT_ENTITY ie = m_listInspectEntity[i];
	//			//if (ie.bHasPin1 == bHasPin1)
	//			{
	//				imageView->GetHalconBuffer()->DispText(i + 1, "image", ie.coordinate.x() - 5, ie.coordinate.y() - 5, "yellow", "box_color", "black");
	//			}
	//		}
	//	}
	//}

	imageView->GetHalconBuffer()->FlushBuffer();
}

void LgaImageProcess::ShowAndSave(BOOL bSave)
{
	if (m_curRes == ResultManager::ERR_MAX)
	{
		qDebug() << "error code max";
		return;
	}
	
	ShowAllResult();

	if (bSave)
	{
		/*InspectImageThread *thread = new InspectImageThread(this);
		thread->SetOpType(1);
		thread->start();*/
		SaveResultImage(ResultManager::ERR_PASS == m_curRes);
	}
	ReleaseBuffer();
}

void LgaImageProcess::ReleaseBuffer()
{
	try
	{
		//PACKAGE_INFO info = StaticFunction::GetPackageInfo();
		m_imagePadList.clear();
		m_imageSubList.clear();
		m_imageCapList.clear();
		//for (int i = 1; i <= 4; i++)
		//{
		//	//if (info.lightConfigSubstrate.catchProp & (1 << (i - 1)))
		//	{
		//		if (m_imageSubList[i - 1].IsInitialized())
		//		{
		//			m_imageSubList[i - 1] = HImage();
		//		}
		//	}
		//	//if (info.lightConfigPad.catchProp & (1 << (i - 1)))
		//	{
		//		if (m_imagePadList[i - 1].IsInitialized())
		//		{
		//			m_imagePadList[i - 1] = HImage();
		//		}
		//	}
		//	if (i<=2)
		//	{
		//		if (m_imageCapList[i - 1].IsInitialized())
		//		{
		//			m_imageCapList[i - 1] = HImage();
		//		}
		//	}
		//}

		//for (int i = 0; i < 4; i++)
		//{
		//	QUAR_ANALYSIZE qa = m_qa[i];
		//	if (qa.imagePadPart.IsInitialized())
		//	{
		//		qa.imagePadPart = HImage();
		//	}
		//	if (qa.imageSubPart.IsInitialized())
		//	{
		//		qa.imageSubPart = HImage();
		//	}
		//}
		//m_imageAddR = m_imageAddG = m_imageAddB = m_imageDumpR = m_imageDumpG = m_imageDumpB = HImage();
	}
	catch (HalconCpp::HOperatorException e)
	{
		qDebug() << "release:" << e.ErrorMessage() << e.ProcName();;
	}
}

void LgaImageProcess::SaveResultImage(BOOL bRes)
{
	qDebug() << __FUNCTION__ << m_inspectParam.bOnlySaveFail << bRes;
    if (!m_inspectParam.bOnlySaveFail || (!bRes&&m_inspectParam.bOnlySaveFail))
    {
        QHalconWindow *imageView = (QHalconWindow *)m_widget;
        HImage img = imageView->GetHalconBuffer()->DumpWindowImage();
        ImageSaveManager *ism = ImageSaveManager::getInstance();
        ism->AddImageList(m_imagePadList, m_imageCapList, m_imageSubList, m_ri.lotName, m_time, bRes, img, 1);
    }
}

//void LgaImageProcess::SaveResultImage(BOOL bRes)
//{
//	qDebug() << __FUNCTION__ << "++";
//    QDateTime time1 = QDateTime::currentDateTime();

//	QString currentdate = m_time.toString("yyyy-MM-dd");
//	QString currentime = m_time.toString("hh_mm_ss");

//	QString dirStr = QString("%1/%2").arg(m_path).arg(currentdate);
//	if (m_ri.lotName.length() > 0)
//	{
//		dirStr = QString("%1/%2").arg(m_path).arg(m_ri.lotName);
//	}
//	if (m_inspectParam.bSeperateFolder)
//	{
//		dirStr = QString("%1/%2/%3_%4").arg(m_path).arg(currentdate).arg(LgaPackageManager::getInstance()->getPackageType()).arg(m_iInspectCount / m_inspectParam.iCountForSeperateFolder + 1);
//		m_iInspectCount++;
//	}
//	QDir dir;
//	if (!dir.exists(dirStr))
//	{
//		dir.mkpath(dirStr);
//		//qDebug() << "mkpath" << dir_str << res;
//	}

//	if (!m_inspectParam.bOnlySaveFail || (!bRes&&m_inspectParam.bOnlySaveFail))
//	{
//		QString appName = QCoreApplication::applicationName();
//		QSettings app(appName, "Debug");
//		QStringList list;
//		list << "bmp" << "png fastest" << "png";

//		int index = app.value("imagetype").toInt();
//		if (index >= list.count() || index < 0)
//		{
//			index = 0;
//		}
//		QString ext = list[index];
//		for (int i = 0; i < m_imagePadList.count(); i++)
//		{
//			HImage image = m_imagePadList[i];

//			if (image.IsInitialized())
//			{
//				QString file = QString("%1/%2_pad%3").arg(dirStr).arg(currentime).arg(i+1);
//				image.WriteImage(ext.toUtf8(), 0, file.toUtf8());
//			}
//		}
//		for (int i = 0; i < m_imageSubList.count(); i++)
//		{
//			HImage image = m_imageSubList[i];

//			if (image.IsInitialized())
//			{
//				QString file = QString("%1/%2_edge%3").arg(dirStr).arg(currentime).arg(i+1);
//				image.WriteImage(ext.toUtf8(), 0, file.toUtf8());
//			}
//		}
//		for (int i = 0; i < m_imageCapList.count(); i++)
//		{
//			HImage image = m_imageCapList[i];

//			if (image.IsInitialized())
//			{
//				QString file = QString("%1/%2_cap%3").arg(dirStr).arg(currentime).arg(i+1);
//				image.WriteImage(ext.toUtf8(), 0, file.toUtf8());
//			}
//		}
//		QString str = bRes ? "P" : "F";
//		QString fileReuslt = QString("%1/%2_%3").arg(dirStr).arg(currentime).arg(str);
//		QHalconWindow *imageView = (QHalconWindow *)m_widget;
//		imageView->GetHalconBuffer()->DumpWindow(m_imgType.toUtf8(), fileReuslt.toUtf8());
//	}
//	QDateTime time2 = QDateTime::currentDateTime();
//	qint64 msec = time1.msecsTo(time2);
//	qDebug() << __FUNCTION__ << "--" << msec;
//}
